#ifndef PUSH_BUTTON_H
#define PUSH_BUTTON_H

#include "checkable_menu.h"

#include <QPushButton>
#include <QHash>
#include <QList>
#include <QPair>

// usage example
//
//    checkable_menu::tree tree;
//    tree.add_node( { std::make_tuple("key_points", "points", 1, 0), std::make_tuple("key_radars", "radars", 1, 0), std::make_tuple("key_airdroms", "airdroms", 1, 0) } );
//              // add top level elements points, radars, airdroms (in main menu)
//    tree.add_node( "key_points", { std::make_tuple("key_points1", "points1", 1, 0), std::make_tuple("key_points2", "points2", 1, 0), std::make_tuple("key_points3", "points3", 1, 0) } );
//              //add alements to points menu, which shown when mouse is on "points" in main menu
//    hierarchical_menu_button *menu_button = new hierarchical_menu_button(tree, "objects", 0);
//              // create button with text "objects". when click on this button main menu is shown (with "points", "radars", "airdroms" items)
//
// getting checked state of menu
// to get checked state of main menu - use get_main_menu_state() method. It return list of pairs. first element is menu item name ("points", "radars" or "airdroms"), second - check state as bool
// to get state of sub menu use get_menu_state(const QString &key)
// for example get_menu_state("points") return state of "points1", "points2" and "points3" item from submenu "points"
//
// if you want to add submenu to existing menu use add_menu method
//
//    checkable_menu::tree t;
//    t.add_node( { std::make_tuple("key_radars1", "radars1", 1, 0), std::make_tuple("key_radars2", "radars2", 1, 0), std::make_tuple("key_radars3", "radars3", 1, 0) } );
//    menu_button->add_menu("radars", t);
//
// This add submenu with items "radars1", "radars2", "radars3" to menu item radars(which in main menu)

class hierarchical_menu_button
        : public QPushButton
{
    Q_OBJECT
public:
    typedef QPair<QString, bool>     menu_state_t;       // menu_name, check_state
    typedef QList<menu_state_t>      menu_state_list_t;
    typedef std::tuple<QString, int, QVariant> menu_data_t;

public:
    explicit hierarchical_menu_button(const checkable_menu::tree &data, QWidget *parent = 0);
    explicit hierarchical_menu_button(const checkable_menu::tree &data, const QString &button_text, QWidget *parent = 0);

    void add_menu    (const QString &parent_key, const checkable_menu::tree &data);
    void set_checked (const QString &key, bool checked);
    void set_enabled (const QString &key, bool enabled);

    menu_state_list_t get_menu_state     (const QString &key) const;
    menu_state_list_t get_main_menu_state()                   const;
    bool              has_key            (const QString &key) const;

Q_SIGNALS:
    void check_state_changed(const QString &key, int type, QVariant id, bool checked);

private Q_SLOTS:
    void on_menu_hide();
    void on_check_changed(QAction *act);

private:
    enum data_key_t
    {
        dk_key_string = 0,
        dk_type,
        dk_value
    };

private:
//    void mousePressEvent(QMouseEvent *e);
//    void enterEvent     (QEvent      *e);
//    void leaveEvent     (QEvent      *e);
    bool eventFilter(QObject *obj, QEvent *e);

private:
    void add_menu(const checkable_menu::tree &data, const std::vector<QString> &children, checkable_menu::menu *menu);
    void init    (const checkable_menu::tree &data);

private:
    checkable_menu::menu      *main_menu_;
    QHash<QString, QAction*>   action_hash_;
};

Q_DECLARE_METATYPE(hierarchical_menu_button::menu_data_t);

#endif // PUSH_BUTTON_H
